package map;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import errors.StratumNotFoundException;

//TODO in un futuro questa classe potrebbe direttamente estendere Vector<FOREGROUNDS>. al momento non l'ho fatto in quanto voglio solo funzioni utili alla classe!

/*FORMAX aspetta... e se la chiave fosse una chiave composta fatta da LIVELLO_STRATO+IDENTIFICATORE_DELLO_UTENTE ????
 * noooo... idea baelnga... ho provato a farlo ma è troppo complesso rispetto la lista... le prestazioni si degraderebbero! -.-'
 */

/**rappresenta uno strato di foregrounds all'interno di una mappa. Ogni strato
 * può contenere un numero arbitrario di foregrounds, <strong>anche nessuno</strong>.
 * 
 * 
 * @author Koldar
 * @version 1.0
 *
 * @param <FOREGROUNDS> indica il tipo di contenitore che contiene i vari foregrounds
 * @deprecated non ha senso creare una struttura del genere.. per il momento (ma magari più in lato per la leggibilità si potrebbe riusare!)
 */
@Deprecated
public abstract class Stratum<FOREGROUNDS> implements Serializable{

	private static final long serialVersionUID = 7597967974543165028L;
	/**rappresenta la lista di strati ognuno contenente una serie (anche vuota) di foregrounds*/
	protected List<FOREGROUNDS> stratiLevels;

	/**costruisce una nuova struttura dati per inglobare i foregrounds
	 * 
	 */
	public Stratum(){
		super();
	}
	
	/**aggiunge un nuovo strato al di sopra di quello specificato dall'indirizzo <tt>index</tt>.
	 * In caso l'indirizzo <tt>index</tt> non rappresenti alcuno strato, viene lanciata
	 * un'eccezione
	 * 
	 * @param index indica lo strato sottostante a quello da inserire
	 * @param newstratum indica il nuovo strato da aggiungere
	 * @throws StratumNotFoundException in caso in cui <tt>index</tt> non punti ad alcuno strato
	 */
	public void addStratum(int index,FOREGROUNDS newstratum) throws StratumNotFoundException{
		try{
			this.stratiLevels.add(index, newstratum);
		} catch (ArrayIndexOutOfBoundsException error){
			throw new StratumNotFoundException(index);
		}
	}
	/**aggiunge il nuovo strato in cima alla mappa
	 * 
	 * @param newstratum il nuovo strato da aggiungere
	 */
	public void addStratum(FOREGROUNDS newstratum){
		try {
			this.addStratum(this.stratiLevels.size()-1, newstratum);
		} catch (StratumNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**dato il livello dello strato, ritorna una mappatura di tutti i foregrounds inclusi in quello
	 * strato
	 * 
	 * @param index l'indice dello strato da reperire
	 * @throws StratumNotFoundException in caso l'indice non rappresenti uno strato
	 * @return l'elenco dei foregrounds contenuti nello strato
	 */
	public FOREGROUNDS getStratum(int index) throws StratumNotFoundException{
		try{
			return this.stratiLevels.get(index);
		}catch (ArrayIndexOutOfBoundsException error){
			throw new StratumNotFoundException(index);
		}
	}
	
	public void removeStratum(int index) throws StratumNotFoundException{
		try{
			this.stratiLevels.remove(index);
		} catch (ArrayIndexOutOfBoundsException error){
			throw new StratumNotFoundException(index);
		}
	}
	/**
	 * 
	 * @return l'elenco dei foregrounds alla base della mappa
	 */
	public FOREGROUNDS getLowestStratum(){
		return this.stratiLevels.get(0);
	}
	/**
	 * 
	 * @return l'elenco dei foregrounds in cima alla mappa
	 */
	public FOREGROUNDS getUppestStratum(){
		return this.stratiLevels.get(this.stratiLevels.size()-1);
	}
	
	/**
	 * 
	 * @return l'iteratore con cui è possibile scorrere velocemente tutti gli strati dello Stratum
	 */
	public Iterator<FOREGROUNDS> getIterator(){
		return this.stratiLevels.iterator();
	}
	
	//TODO da eliminare poiché non deve essere visibile il stratiLevels
	/**
	 * @return the stratiLevels
	 */
	public List<FOREGROUNDS> getStratiLevels() {
		return stratiLevels;
	}
	
	//TODO da eliminare poiché non deve essere visibile il stratiLevels
	/**
	 * @param stratiLevels the stratiLevels to set
	 */
	public void setStratiLevels(Vector<FOREGROUNDS> stratiLevels) {
		this.stratiLevels = stratiLevels;
	}
	
	
	
	
}
